home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
util1
/
yk211src.lha
/
Yak_2.11_Src
/
WBStartup
/
Patch_libs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-18
|
5KB
|
170 lines
/*
** Contains all necessary functions to patch libraries functions safely.
** Theses functions are largely inspired from ISpy.c which can be found in
** the Amiga Mail archive (available from Fred Fish collection).
**
** Author: Gael Marziou
** Created: 14 July 1994 (Bastille Day ;-)
**
*/
#include "code.h"
#include "Patch_Libs.h"
struct JumpTable *
GetJumpTable(UBYTE *name, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UWORD *jmpinstr;
UBYTE *jtname;
UCOUNT i, j;
/* Not really necessary to forbid again, just to indicate that I don't
* want another task to create the semaphore while I'm trying to do the
* same. Here GetJumpTable() is only called from InstallWedge(), so it
* will just bump the forbid count.
*/
Forbid();
if (!(jumptable = (struct JumpTable *) FindSemaphore(name)))
{
/* No jump table we have to allocate it */
if (jumptable = AllocMem(sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6),
MEMF_PUBLIC | MEMF_CLEAR))
{
if (jtname = AllocMem(strlen(name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
{
for (i = 0, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
{
jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
*jmpinstr = 0x4EF9;
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
*addressptr = (ULONG) SetFunction(
(struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
LVOArray[j].lt_LVO,
(VOID *) ((UBYTE *) jumptable->jt_Function + i));
}
jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
strcpy(jtname, name);
jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
AddSemaphore((struct SignalSemaphore *) jumptable);
}
else
{
FreeMem(jumptable, sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6));
jumptable = NULL;
}
}
}
/* Clear the cpu's cache so the execution cache is valid */
CacheClearU();
Permit();
/* If succeeded, you now have a jumptable which entries point to the original
* library functions. If another task SetFunction()'ed one or more of those
* already, that task can never go away anymore.
*/
return (jumptable);
}
BOOL
InstallWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UCOUNT i, j;
Forbid();
/* Get pointer to JumpTable. Create it if necessary */
if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
{
/* Try to get exclusive lock on semaphore, in case it already existed. */
if (AttemptSemaphore((struct SignalSemaphore *) jumptable))
{
/* Make sure nobody else has function addresses in the jumptable */
if (jumptable->jt_Owner == NULL)
{
jumptable->jt_Owner = FindTask(0);
/* Don't want to disable any longer than necessary */
Disable();
for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
{
/* Replace addresses in the jumptable with my own. */
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
(*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
*addressptr = (ULONG) LVOArray[j].lt_newFunction;
}
Enable();
}
ReleaseSemaphore((struct SignalSemaphore *) jumptable);
}
}
/* Clear the cpu's cache so the execution cache is valid */
CacheClearU();
Permit();
return ((BOOL) jumptable);
}
BOOL
RemoveWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UCOUNT i, j;
Forbid();
if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
{
/* Check if this task owns this jumptable */
if (jumptable->jt_Owner == FindTask(0))
{
/* Get the semaphore exclusively.
* Depending on what got SetFunction()'ed this could take some time.
* Also note that shared locks are used to indicate the code is
* being executed and that shared locks can jump ahead of queue'ed
* exclusive locks, adding to the waittime.
*/
ObtainSemaphore((struct SignalSemaphore *) jumptable);
Disable();
/* Restore old pointers in jumptable */
for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
{
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
*addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
}
Enable();
jumptable->jt_Owner = NULL;
ReleaseSemaphore((struct SignalSemaphore *) jumptable);
}
}
/* Clear the cpu's cache so the execution cache is valid */
CacheClearU();
Permit();
return (TRUE);
}